package ru.nsu.fit.client.core.soap.GetQuestions;

import org.ksoap2.serialization.PropertyInfo;
import org.ksoap2.serialization.SoapObject;
import ru.nsu.fit.client.core.Question;
import ru.nsu.fit.client.core.response.QuestionsData;
import ru.nsu.fit.client.core.soap.SOAPExecutor;

import java.util.*;

public class GetQuestions {
    private static final String WSDL_NAME = "get_questions";
    private static final String METHOD_NAME = "getQuestions";
    private static final String NAMESPACE = "http://get_questions.ws.fit.nsu.ru/";

    public static GetQuestionsOutput execute(final String serverLocation, long userSessionId, int questionNumber, int questionsOffset, int latitude, int longitude, int radius) throws Exception
    {
        String wsdlLocation = serverLocation + WSDL_NAME + "?wsdl";

        Set<Map.Entry<String, String>> params = new HashSet<Map.Entry<String,String>>();
        params.add(new AbstractMap.SimpleEntry<String, String>("userSessionId", String.valueOf(userSessionId)));
        params.add(new AbstractMap.SimpleEntry<String, String>("questionNumber", String.valueOf(questionNumber)));
        params.add(new AbstractMap.SimpleEntry<String, String>("questionsOffset", String.valueOf(questionsOffset)));
        params.add(new AbstractMap.SimpleEntry<String, String>("latitude", String.valueOf(latitude)));
        params.add(new AbstractMap.SimpleEntry<String, String>("longitude", String.valueOf(longitude)));
        params.add(new AbstractMap.SimpleEntry<String, String>("radius", String.valueOf(radius)));

        SoapObject response = SOAPExecutor.executeSOAP(wsdlLocation, NAMESPACE, METHOD_NAME, params);

        GetQuestionsOutput out = new GetQuestionsOutput();
        if (response.hasProperty("errorMessage"))
        {
            out.setErrorMessage(response.getPropertyAsString("errorMessage"));
        }
        if (response.hasProperty("errorCode"))
        {
            out.setErrorCode(Integer.parseInt(response.getPropertyAsString("errorCode")));
        }

        PropertyInfo info = new PropertyInfo();
        ArrayList<Integer> questionIds = new ArrayList<Integer>();
        ArrayList<Integer> lifetimes = new ArrayList<Integer>();
        ArrayList<String> questionTexts = new ArrayList<String>();
        ArrayList<ArrayList<Integer>> answerIds = new ArrayList<ArrayList<Integer>>();
        ArrayList<ArrayList<String>> answers = new ArrayList<ArrayList<String>>();

        for (int i = 0; i < response.getPropertyCount(); ++i)
        {
            response.getPropertyInfo(i, info);
            if (info.getName().equals("questionIds"))
            {
                questionIds.add(Integer.parseInt(info.getValue().toString()));
            }
            else if (info.getName().equals("lifetimes"))
            {
                lifetimes.add(Integer.parseInt(info.getValue().toString()));
            }
            else if (info.getName().equals("questionTexts"))
            {
                questionTexts.add(info.getValue().toString());
            }
            else if (info.getName().equals("answers"))
            {
                SoapObject prop = (SoapObject)info.getValue();
                ArrayList<String> array = new ArrayList<String>();
                for (int j = 0; j < prop.getPropertyCount(); ++j)
                {
                    array.add(prop.getPropertyAsString(j));
                }
                answers.add(array);
            }
            else if (info.getName().equals("answerIds"))
            {
                SoapObject prop = (SoapObject)info.getValue();
                ArrayList<Integer> array = new ArrayList<Integer>();
                for (int j = 0; j < prop.getPropertyCount(); ++j)
                {
                    array.add(Integer.parseInt(prop.getPropertyAsString(j)));
                }
                answerIds.add(array);
            }
        }

        QuestionsData data = new QuestionsData();
        for (int i = 0; i < questionIds.size(); ++i)
        {
            Question question = new Question(questionIds.get(i), questionTexts.get(i), lifetimes.get(i));
            question.setCaseIds(answerIds.get(i));
            question.setCases(answers.get(i));
            data.getQuestions().add(question);
        }

        out.setData(data);

        return out;
    }
}
